import { BeforeOpenModalResult, ElementPropertyConfig, KeyMap, PropertyChangeObject, PropertyEntity } from '@farris/ide-property-panel';
import { EditorTypes } from '@farris/ui-datagrid-editors';
import { ItemCollectionConverter, ItemCollectionEditorComponent, StyleEditorComponent } from '@farris/designer-devkit';
import { FormPropertyChangeObject } from '../../../../entity/property-change-entity';
import { InputProps } from '../../common/property/input-property-config';
import { RichTextEditorComponent } from '@farris/rich-text-designer';

export class RichTextBoxProp extends InputProps {

    propertyConfig: ElementPropertyConfig[];


    getPropConfig(propertyData: any): ElementPropertyConfig[] {

        this.propertyConfig = [];

        // 基本信息属性
        const basicPropConfig = this.getBasicPropConfig(propertyData, this.viewModelId);
        this.propertyConfig.push(basicPropConfig);

        // 外观属性
        const appearanceProperties = this.getAppearancePropConfig(propertyData, this.viewModelId);
        this.propertyConfig.push(appearanceProperties);

        // 行为属性
        const behaviorPropConfig = this.getBehaviorPropConfig(propertyData, this.viewModelId);
        this.propertyConfig.push(behaviorPropConfig);

        // 表达式属性
        const exprPropConfig = this.getExpressionPropConfig(propertyData, this.viewModelId);
        if (exprPropConfig) {
            this.propertyConfig.push(exprPropConfig);
        }
        // 事件属性
        const eventPropConfig = this.getEventPropertyConfig(propertyData, this.viewModelId);
        this.propertyConfig.push(eventPropConfig);

        return this.propertyConfig;
    }


    private getAppearancePropConfig(propertyData: any, viewModelId: string, showPosition = 'card'): ElementPropertyConfig {
        let appearanceProperties = [];
        if (showPosition === 'card' || showPosition === 'tableTdEditor') {
            appearanceProperties = this.getAppearanceCommonPropConfig(propertyData, viewModelId, showPosition);
        }
        const placeHolder = appearanceProperties.find(p => p.propertyID === 'placeHolder');
        if (placeHolder) {
            placeHolder.controlSource = 'concise';
        }
        appearanceProperties.push(
            {
                propertyID: 'controlSource',
                propertyName: '主题类型',
                propertyType: 'select',
                description: '组件的控件主题类型',
                iterator: [{ key: 'concise', value: '简洁' }, { key: 'advanced', value: '高级' }]
            },
            {
                propertyID: 'theme',
                propertyName: '编辑器主题',
                propertyType: 'select',
                description: '控件主题类型为简洁时编辑器主题',
                iterator: [{ key: 'snow', value: 'snow' }, { key: 'bubble', value: 'bubble' }],
                controlSource: 'concise'
            },
            {
                propertyID: 'minLength',
                propertyName: '最小长度',
                propertyType: 'number',
                description: '控件主题类型为简洁时编辑器最小长度',
                decimals: 0,
                min: 0,
                controlSource: 'concise'
            },
            {
                propertyID: 'customToolbarPosition',
                propertyName: '自定义工具条位置',
                propertyType: 'select',
                description: '控件主题类型为简洁时工具条位置设置',
                iterator: [{ key: 'top', value: '顶部' }, { key: 'bottom', value: '底部' }],
                controlSource: 'concise'
            },
            {
                propertyID: 'customEditorStyle',
                propertyName: '自定义编辑区样式',
                propertyType: 'modal',
                description: '控件主题类型为简洁时编辑区样式设置',
                editor: StyleEditorComponent,
                showClearButton: true,
                controlSource: 'concise'
            },
            {
                propertyID: 'fontFamilyList',
                propertyName: '字体列表',
                propertyType: 'modal',
                description: '控件主题类型为高级时字体可选列表',
                editor: ItemCollectionEditorComponent,
                converter: new ItemCollectionConverter(),
                editorParams: {
                    columns: [
                        { field: 'value', title: '字体', editor: { type: EditorTypes.TEXTBOX } },
                    ],
                    requiredFields: ['value'],
                    uniqueFields: ['value'],
                    modalTitle: '字体列表',
                    canEmpty: true,
                    isSimpleArray: true
                },
                showClearButton: true,
                controlSource: 'advanced'
            },
            {
                propertyID: 'defaultFontFamily',
                propertyName: '默认字体',
                propertyType: 'select',
                description: '控件主题类型为高级时默认字体类型',
                iterator: this.getDefaultFontFamilyIterator(propertyData.fontFamilyList),
                controlSource: 'advanced'
            },
            {
                propertyID: 'customToolbar',
                propertyName: '启用自定义功能项',
                propertyType: 'boolean',
                defaultValue: false
            },
            {
                propertyID: 'toolbar',
                propertyName: '自定义功能项配置',
                propertyType: 'modal',
                visible: propertyData.customToolbar,
                editor: RichTextEditorComponent,
                editorParams: {
                    editorType: propertyData.controlSource,
                    enablePreview: false,
                    enableCode: false
                },
                beforeOpenModal(): BeforeOpenModalResult {
                    // 取类型最新值
                    this.editorParams.editorType = propertyData.controlSource;
                    return { result: true, message: '' };
                }
            }
        );
        appearanceProperties.forEach((p: PropertyEntity) => {
            if (p.controlSource) {
                p.visible = propertyData.controlSource === p.controlSource;
            }
        });

        const self = this;
        const config = {
            categoryId: 'appearance',
            categoryName: '外观',
            properties: appearanceProperties,
            setPropertyRelates(changeObject: FormPropertyChangeObject, prop, parameters) {
                if (!changeObject) {
                    return;
                }
                self.changeAppearancePropertyRelates(this.properties, changeObject, propertyData, parameters);
                switch (changeObject.propertyID) {
                    case 'controlSource': {
                        this.properties.map(p => {
                            if (p.controlSource) {
                                p.visible = p.controlSource === changeObject.propertyValue;
                            }
                        });
                        propertyData.toolbar = null;
                        break;
                    }
                    case 'fontFamilyList': {
                        const defaultFontFamily = this.properties.find(p => p.propertyID === 'defaultFontFamily');
                        if (defaultFontFamily) {
                            defaultFontFamily.iterator = self.getDefaultFontFamilyIterator(changeObject.propertyValue);
                        }
                        if (changeObject.propertyValue) {
                            propertyData.defaultFontFamily = changeObject.propertyValue.includes(propertyData.defaultFontFamily) ?
                                propertyData.defaultFontFamily : '';
                        } else {
                            propertyData.defaultFontFamily = '';
                        }

                        break;
                    }
                    case 'customToolbar': {
                        const toolbar = this.properties.find(p => p.propertyID === 'toolbar');
                        if (toolbar) {
                            toolbar.visible = changeObject.propertyValue;
                        }
                        break;
                    }
                }
            }
        };

        if (showPosition !== 'card') {
            Object.assign(config, {
                categoryId: showPosition + '_' + config.categoryId,
                propertyData,
                enableCascade: true,
                parentPropertyID: 'editor',
                tabId: showPosition,
                tabName: '编辑器'
            });
        }
        return config;
    }

    private getBehaviorPropConfig(propertyData: any, viewModelId: string, showPosition = 'card'): ElementPropertyConfig {
        let behaviorProperties = [];
        if (showPosition === 'card' || showPosition === 'tableTdEditor') {
            behaviorProperties = this.getBehaviorCommonPropConfig(propertyData, viewModelId);
        }


        const self = this;
        const config = {
            categoryId: 'behavior',
            categoryName: '行为',
            properties: behaviorProperties,
            setPropertyRelates(changeObject: FormPropertyChangeObject, prop, parameters) {
                self.changeBehaviorPropertyRelates(this.properties, changeObject, propertyData, parameters, showPosition);
            }
        };

        if (showPosition !== 'card') {
            Object.assign(config, {
                categoryId: showPosition + '_' + config.categoryId,
                propertyData,
                enableCascade: true,
                parentPropertyID: 'editor',
                tabId: showPosition,
                tabName: '编辑器'
            });
        }
        return config;
    }


    private getDefaultFontFamilyIterator(fontFamilyList: any[]): KeyMap[] {
        if (!fontFamilyList || fontFamilyList.length === 0) {
            return [];
        }
        const iterators = [];
        fontFamilyList.forEach(font => {
            iterators.push({
                key: font,
                value: font
            });
        });
        return iterators;
    }

    /**
     * table单元格编辑器属性
     * @param tdData 单元格数据
     * @param viewModelId viewModelId
     * @returns 属性配置
     */
    getTableTdEdtiorPropConfig(tdData: any, viewModelId: string): ElementPropertyConfig[] {
        const propertyData = tdData.editor;

        this.propertyConfig = [];

        // 外观属性
        const appearanceConfig = this.getAppearancePropConfig(propertyData, viewModelId, 'tableTdEditor');
        this.propertyConfig.push(appearanceConfig);

        // 行为属性
        const behaviorConfig = this.getBehaviorPropConfig(propertyData, viewModelId, 'tableTdEditor');
        behaviorConfig.properties = behaviorConfig.properties.filter(p => !'binding,visible'.includes(p.propertyID));
        this.propertyConfig.push(behaviorConfig);


        // 表达式属性
        const exprPropConfig = this.getExpressionPropConfig(propertyData, viewModelId, 'tableTdEditor');
        if (exprPropConfig) {
            this.propertyConfig.push(exprPropConfig);
        }

        // 事件属性
        const eventPropConfig = this.getEventPropertyConfig(propertyData, this.viewModelId, 'tableTdEditor');
        this.propertyConfig.push(eventPropConfig);

        return this.propertyConfig;
    }

}
